 package com.ee.bruscar.example.business;

import java.util.Map;
import java.util.HashMap;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;
import com.ee.bruscar.example.model.general.AllBasicTypes;
import com.ee.bruscar.example.model.general.ImageLink;
import com.ee.bruscar.example.model.general.NewsItem;

/**
 * This class is automatically generated.
 */
public class ContentDelegateStub implements com.ee.bruscar.example.business.ContentDelegate
{
	private Map<String,String> hintMap;
	private DataMaker maker;
	
	public ContentDelegateStub()
	{
		maker = new DataMaker();
		
		hintMap = new HashMap<String, String>();
		 
		hintMap.put( "getFrontPageImageLink.ImageLink.label", "Frontpage" ); 
		hintMap.put( "getFrontPageImageLink.ImageLink.url", "http://google.com" );
		 
		hintMap.put( "getRandomImageLink.ImageLink.label", "Random1,Random2,Random3,Random4," ); 
		hintMap.put( "getRandomImageLink.ImageLink.url", "http://google.com,http://bbc.co.uk,http://danskespil.dk" );
		 
		hintMap.put( "getNewsItem.NewsItem.link", "newsItemLinkReference" ); 
		hintMap.put( "getNewsItem.NewsItem.title", "NewsItem title" );
		 
		hintMap.put( "getRandomImageLinkList.ImageLink.label", "ListRandom1,ListRandom2,ListRandom3,ListRandom4," ); 
		hintMap.put( "getRandomImageLinkList.ImageLink.url", "http://google.com,http://bbc.co.uk,http://danskespil.dk" );
		hintMap.put( "getRandomImageLinkList.range", "10-20");
		 
		//generic hint
		hintMap.put( "ImageLink.label", "genericModelHint" ); 
		//generic hint
		hintMap.put( "ImageLink.url", "http://generichint.com" );
		 
		//referenced hint
		hintMap.put( "newsItemLinkReference.ImageLink.label", "link to news1, link to news 2, link to news 3" ); 
		//referenced hint
		hintMap.put( "newsItemLinkReference.ImageLink.url", "http://newsitem.com,http://bbc.co.uk/news,http://rte.ie/news" );
		 
		//generic hint
		hintMap.put( "AllBasicTypes.dateValue", "2007-2009" );
	}
	
	
	/**
	 * Interface methods
	 */
	public ImageLink getFrontPageImageLink( java.lang.String arg1 )
	{
		return createStubImageLink( "getFrontPageImageLink" );
	} 

	public ImageLink getRandomImageLink( java.lang.String arg1 )
	{
		return createStubImageLink( "getRandomImageLink" );
	} 

	public List<ImageLink> getRandomImageLinkList( java.lang.String arg1 )
	{
		List<ImageLink> returnList = new ArrayList<ImageLink>();
		int maxCount = getReturnCountFor( "getRandomImageLinkList.range" );
		for( int i = 0 ; i < maxCount ; i++ )
		{
			returnList.add( createStubImageLink( "getRandomImageLinkList" ) );
		}
		return returnList;
	} 


	public ImageLink getUnhintedImageLink( java.lang.String arg1 )
	{
		return createStubImageLink( "getUnhintedImageLink" );
	} 

	public NewsItem getNewsItem(  )
	{
		return createStubNewsItem( "getNewsItem" );
	} 

	public AllBasicTypes getBasicTypes(  )
	{
		return createStubAllBasicTypes( "getBasicTypes" );
	} 
	
	/**
	 * custom class generators
	 */
	private com.ee.bruscar.example.model.general.AllBasicTypes createStubAllBasicTypes( String methodName )
	{
		com.ee.bruscar.example.model.general.AllBasicTypes stub = new com.ee.bruscar.example.model.general.AllBasicTypes();
		stub.setStringValue( (String) getStubFor( methodName + ".AllBasicTypes.stringValue", String.class ) );
		stub.setDateValue( (Date) getStubFor( methodName + ".AllBasicTypes.dateValue", Date.class ) );
		stub.setIntValue( getStubIntFor( "AllBasicTypes.intValue" ) );
		stub.setBooleanValue( getStubBooleanFor( "AllBasicTypes.booleanValue" ) );
		stub.setDoubleValue( getStubDoubleFor( "AllBasicTypes.doubleValue" ) );
		stub.setLongValue( getStubLongFor( "AllBasicTypes.longValue" ) );
		return stub;
	}


	private com.ee.bruscar.example.model.general.ImageLink createStubImageLink( String methodName )
	{
		com.ee.bruscar.example.model.general.ImageLink stub = new com.ee.bruscar.example.model.general.ImageLink();
		stub.setUrl( (String) getStubFor( methodName + ".ImageLink.url", String.class ) );
		stub.setLabel( (String) getStubFor( methodName + ".ImageLink.label", String.class ) );
		return stub;
	}


	private com.ee.bruscar.example.model.general.NewsItem createStubNewsItem( String methodName )
	{
		com.ee.bruscar.example.model.general.NewsItem stub = new com.ee.bruscar.example.model.general.NewsItem();
		String hintId = resolveHintId( methodName, "NewsItem", "link" );
		stub.setLink( createStubImageLink( hintId ) );

		stub.setTitle( (String) getStubFor( methodName + ".NewsItem.title", String.class ) );
		return stub;
	}

	
	
	/**
	 * list stubs
	 */
	
	/**
	 * non dynamic stubbing logic
	 */
	private Object getStubFor( String fieldName, Class<?> typeExpected )
	{
		if( hintMap.containsKey(fieldName) )
		{
			return maker.createData( hintMap.get( fieldName ), typeExpected );
		}
		
		int firstDotIndex = fieldName.indexOf(".");
		String modelOnlyKey = fieldName.substring(firstDotIndex + 1 );
		
		if( hintMap.containsKey(modelOnlyKey))
		{
			return maker.createData(hintMap.get( modelOnlyKey ), typeExpected);
		}
			
		return getGenericValue( fieldName, typeExpected );
	}
	//Primitive stub generators
	private int getStubIntFor( String fieldName )
	{
		if( hintMap.containsKey( fieldName ))
		{
			Integer val = (Integer) maker.createData( hintMap.get( fieldName ), Integer.class );
			return val.intValue();
		}
		return 0;
	}

	private double getStubDoubleFor( String fieldName )
	{
		if( hintMap.containsKey( fieldName ))
		{
			Double val = (Double) maker.createData( hintMap.get( fieldName ), Double.class );
			return val.doubleValue();
		}
		return 0.0;
	}

	private long getStubLongFor( String fieldName )
	{
		if( hintMap.containsKey( fieldName ))
		{
			Long val = (Long) maker.createData( hintMap.get( fieldName ), Long.class );
			return val.longValue();
		}
		return 0;
	}

	private boolean getStubBooleanFor( String fieldName )
	{
		return true;
	}	
		
		
	private int getReturnCountFor(String methodListRangeKey )
	{
		if( hintMap.containsKey( methodListRangeKey ))
		{
			Integer val = (Integer) maker.createData( hintMap.get( methodListRangeKey ), Integer.class );
			return val.intValue();
		}
		
		return 10;
	}

	private String resolveHintId( String nameToResolve, String returnTypeName, String field  )
	{
		String lookup = nameToResolve + "." + returnTypeName + "." + field;
		
		if( hintMap.containsKey( lookup ) )
		{
			String value = hintMap.get(lookup);
			return value;
		}
		return nameToResolve + "." + returnTypeName ;
	}

	private Object getGenericValue( String fieldName, Class<?> typeExpected )
	{
		if( typeExpected == String.class )
		{
			return fieldName;
		}
		if( typeExpected == Date.class )
		{
			return new Date();
		}
		return null;
	}

	public class DataMaker
	{
		private Map<Class<?>, Maker> makerMap;
		
		public DataMaker()
		{
			makerMap = new HashMap<Class<?>, Maker>();
			makerMap.put(String.class, new StringMaker() );
			makerMap.put(Date.class, new DateMaker() );
			makerMap.put(Integer.class, new IntegerMaker() );
		}
		
		public Object createData(String hint, Class<?> typeExpected )
		{
			Maker maker = makerMap.get( typeExpected );
			if( maker == null )
			{
				throw new RuntimeException("Couldn't find maker for: " + typeExpected.getName() );
			}
			return maker.createData(hint);
		}

		public abstract class Maker
		{
			public abstract Object createData( String hint );
		}
		
		private class StringMaker extends Maker
		{
			public String createData(String hint )
			{
				String[] items = hint.split(",");
				int index = getRandomIndex( items.length );
				return items[index];
			}

			private int getRandomIndex(int length)
			{
				double random = Math.random();
				double multiplied = random * length;
				
				Double dbl = new Double( multiplied );
				return dbl.intValue();
			}
		}
			
		private class DateMaker extends Maker
		{
			public Date createData( String hint )
			{
				String[] items = hint.split("-");
				String startYear = items[0];
				String endYear = items[1];
				long startUtc = getTimeInMilliseconds( startYear );
				long endUtc = getTimeInMilliseconds( endYear );
				
				long difference = endUtc - startUtc;
				long multiplied = Math.round( Math.random() * difference );
				long randomDateInMilliseconds = startUtc + multiplied;
				Calendar calendar = new GregorianCalendar();
				calendar.setTimeInMillis( randomDateInMilliseconds );
				return calendar.getTime();
			}
			
			
			private long getTimeInMilliseconds( String year )
			{
				Calendar startDate = new GregorianCalendar( Integer.parseInt(year), 0, 0 );
				return startDate.getTimeInMillis();
			}
		}
		
		private class IntegerMaker extends Maker
		{
			public Integer createData( String hint )
			{
				String[] items = hint.split("-");
				int lowerRange = Integer.parseInt( items[0] );
				int higherRange = Integer.parseInt( items[1] );
				int difference = higherRange - lowerRange;
				double random = Math.random();
				double multiplied = random * difference;
				Double outVal = new Double( multiplied + lowerRange );
				return new Integer( outVal.intValue() );
			}
		}
	}

}